package com.zbs.framework.pay.service.impl;

import com.zbs.framework.common.utils.DateUtils;
import com.zbs.framework.common.utils.ErrorAssert;
import com.zbs.framework.pay.event.AlipayCallbackModel;
import com.zbs.framework.pay.event.OrderAliPaySuccessEvent;
import com.zbs.framework.pay.service.AliPayNewService;
import com.zbs.framework.pay.service.PayCallbackService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Transactional
@Service
public class PayCallbackServiceImpl implements PayCallbackService {

    @Autowired
    private AliPayNewService aliPayNewService;
    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public AlipayCallbackModel alipayCallback(HttpServletRequest request) {
        AlipayCallbackModel model = this.getAlipayCallback(request);
        this.applicationContext.publishEvent(model);
        if (model.getTradeStatus().equals("TRADE_SUCCESS")){
            log.info("--------支付成功------>回执单号：{}，订单号：{}",model.getTradeNo(),model.getOutTradeNo());
            this.applicationContext.publishEvent(new OrderAliPaySuccessEvent(model.getOutTradeNo(),model.getTradeNo()));
        }else {
            log.info("--------扫码中------>回执单号：{}，订单号：{}",model.getTradeNo(),model.getOutTradeNo());
        }
        return model;
    }


    private AlipayCallbackModel getAlipayCallback(HttpServletRequest request) {
        // 1:获取支付宝GET过来反馈信息
        AlipayCallbackModel model = new AlipayCallbackModel();
        Class<? extends AlipayCallbackModel> aClass = model.getClass();
        Map<String, String[]> requestParams = request.getParameterMap();
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; ++i) {
                valueStr = i == values.length - 1 ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            try {
                this.setValues(aClass, model, DateUtils.camelCaseNameByPropertyName(name), valueStr);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            params.put(name, valueStr);
        }
        boolean checked = false;
        try {
            checked = aliPayNewService.verifyNotify(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ErrorAssert.isTrue(checked, "支付宝签名验证失败!");
        return model;
    }

    /**
     * java
     * @param clazz
     * @param obj
     * @param fileName
     * @param value
     * @throws IllegalAccessException
     */
    public void setValues(Class clazz, Object obj, String fileName, String value) throws IllegalAccessException {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.getName().equals(fileName)) {
                field.set(obj, value);
            }
        }
    }
}
